# -*- coding: utf-8 -*-

from threading import Thread, Lock
from time import sleep

import py_global
import logging

logger = logging.getLogger(__name__)


def get_instance(cls, lock, obj, attr: str = 'instance'):
    if not hasattr(cls, attr):
        with lock:  # 线程锁
            if not hasattr(cls, attr):
                setattr(cls, attr, obj)
                pass
            pass
        pass
    return getattr(cls, attr)


class Singleton1(object):
    """
    单例模式1
    """
    lock = Lock()  # 线程锁

    @classmethod
    def get_instance(cls):
        return get_instance(cls, cls.lock, cls())

    pass


class Singleton2(object):
    """
    单例模式2
    """
    lock = Lock()  # 线程锁

    def __new__(cls, *args, **kwargs):
        return get_instance(cls, cls.lock, object.__new__(cls))

    pass


class SingletonMeta(type):
    """
    元类
    """
    lock = Lock()  # 线程锁

    def __call__(cls, *args, **kwargs):
        return get_instance(cls, cls.lock, super(SingletonMeta, cls).__call__(*args, **kwargs))

    pass


class Singleton3(metaclass=SingletonMeta):

    def __init__(self, parameter):
        self.attribute = parameter


def func(i: int):
    # instance = Singleton1.get_instance()
    # instance = Singleton2()
    instance = Singleton3(i)
    logger.info(f'id(instance)={id(instance)}')
    pass


if __name__ == '__main__':
    for i in range(10):
        Thread(target=func, args=[i, ]).start()
        pass
    sleep(0.1)

    # instance = Singleton1.get_instance()
    # instance = Singleton2()
    instance = Singleton3(10)

    logger.info(f'id(instance)={id(instance)}')

    pass
